/*
 * 知识点弹窗选择组件
 */

import * as React from 'react';
import { connect } from 'react-redux';
import { get } from 'lodash';
import { Input, Form, Icon, Tag, Tooltip, Card, Button } from 'antd';

import { isEqualWithNumber } from 'utils/utils';
import CustomModal from 'components/common/CustomModal';

import LoadableComponent from 'components/common/LoadableComponent';
const LoadableCustomPagination = LoadableComponent(() =>
  import('components/common/CustomPagination')
);

import { fetchKnowledgeList, fetchLessonKnowledgeList } from 'actions/knowledge';
import './PopToSelect.scss';

// loading由调用方下发
interface PopToSelectProps {
  dispatch: (action: any) => any;
  onClose: () => any;
  handleSubmitCallback: (ids: number[]) => any;
  form: any;
  loading: boolean;
  knowledgeTotal: number;
  knowledgeList: object[];
  ownItems?: any[];
  selectMax?: number;
  lessonId?: number;
}

interface PopToSelectState {
  selectedItems: any;
}

class PopToSelect extends React.Component<PopToSelectProps, PopToSelectState> {
  pageInit: number;
  pageSizeInit: number;
  filters: any;

  static defaultProps: PopToSelectProps = {
    dispatch: () => {},
    onClose: () => {},
    handleSubmitCallback: () => {},
    form: {},
    loading: false,
    knowledgeTotal: 0,
    knowledgeList: [],
    ownItems: [],
    selectMax: 0,
    lessonId: 0,
  };
  constructor(props: PopToSelectProps) {
    super(props);
    this.state = {
      selectedItems: get(props, 'ownItems', []),
    };

    this.pageInit = 1;
    this.pageSizeInit = 10;
    this.filters = {
      page: this.pageInit,
      pageSize: this.pageSizeInit,
    };
  }

  componentDidMount() {
    this.handleFetchKnowledgeList();
  }

  // 分页回调
  onPageChange = (page: number) => {
    this.handleFetchKnowledgeList({ page });
  };

  /**
   * 查询Knowledge列表
   */
  handleFetchKnowledgeList = (params: any = {}, isSearch: boolean = false) => {
    const { lessonId, dispatch } = this.props;
    this.filters = { ...this.filters, ...params };
    if (isSearch) {
      this.filters.page = this.pageInit;
    }

    // 数据源：
    // 1, 关联到Lesson的知识点
    // 2, 知识点数据池
    if (lessonId) {
      dispatch(fetchLessonKnowledgeList(lessonId, this.filters));
    } else {
      dispatch(fetchKnowledgeList(this.filters));
    }
  };

  handleTrashItem(id: number) {
    const { selectedItems } = this.state;

    let itemIndex = -1;
    selectedItems.some((item: any, index: number) => {
      if (item['id'] === id) {
        itemIndex = index;

        return true;
      }

      return false;
    });

    if (itemIndex >= 0) {
      selectedItems.splice(itemIndex, 1);
    }

    this.setState({
      selectedItems,
    });
  }

  handleCheckChange = (item: any, checked: boolean) => {
    const { selectedItems } = this.state;
    const { selectMax } = this.props;

    if (checked) {
      if (!selectMax || selectedItems.length < selectMax) {
        selectedItems.push(item);
        this.setState({
          selectedItems,
        });
      }
    } else {
      this.handleTrashItem(item.id);
    }
  };

  handleReset = () => {
    this.props.form.resetFields();
  };

  handleSearch = (e: any) => {
    e.preventDefault();

    const { form } = this.props;

    form.validateFields((err: any, values: any) => {
      if (err) return;

      let filters: any = {};
      Object.keys(values).map((key: any) => {
        const val = values[key];
        if (val) {
          filters[key] = val;
        }
      });

      this.handleFetchKnowledgeList(filters, true);
    });
  };

  handleSubmit = () => {
    const { handleSubmitCallback } = this.props;
    const { selectedItems } = this.state;

    const ids = selectedItems.map((knowledge: any) => {
      return knowledge.id;
    });

    if (ids.length > 0) {
      handleSubmitCallback(ids);
    }
  };

  renderSearchPanel() {
    const { getFieldDecorator } = this.props.form;

    return (
      <Form className="ant-form-inline" onSubmit={this.handleSearch}>
        <Form.Item>{getFieldDecorator('name')(<Input placeholder="search by name" />)}</Form.Item>
        <Form.Item>
          <Button size="default" type="primary" htmlType="submit">
            搜索
          </Button>
          <Button className="mg-l-10" size="default" htmlType="reset" onClick={this.handleReset}>
            重置
          </Button>
        </Form.Item>
      </Form>
    );
  }

  renderKnowledges() {
    const { knowledgeList, selectMax } = this.props;
    const { selectedItems } = this.state;

    let renderHtml = null;
    if (knowledgeList.length > 0) {
      const disabled = selectMax && selectedItems.length === selectMax;
      renderHtml = knowledgeList.map((knowledge: any) => {
        let actions = null;
        if (
          !disabled ||
          (selectedItems.length > 0 && isEqualWithNumber(selectedItems[0]['id'], knowledge.id))
        ) {
          actions = {
            onChange: (checked: boolean) => {
              this.handleCheckChange(knowledge, checked);
            },
          };
        }
        return (
          <Tooltip title={knowledge.description} key={knowledge.id}>
            <Tag.CheckableTag
              key={knowledge.id}
              checked={selectedItems.some((item: any) => {
                return item.id === knowledge.id;
              })}
              {...actions}>
              {knowledge.name}&nbsp;&nbsp;
            </Tag.CheckableTag>
          </Tooltip>
        );
      });
    } else {
      renderHtml = (
        <p className="loading-placeholder">
          <Icon type="frown-o" />&nbsp; 还未添加知识点
        </p>
      );
    }
    return renderHtml;
  }

  renderFooterSelected = () => {
    const { selectedItems } = this.state;

    return (
      <Card title="选择的知识点" style={{ textAlign: 'left' }}>
        {selectedItems.length > 0 ? (
          selectedItems.map((item: any) => {
            return (
              <Tooltip title={item.description} key={item.id}>
                <Tag>
                  {item.name}&nbsp;&nbsp;
                  <Icon
                    type="cross"
                    onClick={e => {
                      e.stopPropagation();
                      this.handleTrashItem(item.id);
                    }}
                  />
                </Tag>
              </Tooltip>
            );
          })
        ) : (
          <p className="loading-placeholder">
            <Icon type="frown-o" />&nbsp; 还没有选择知识点哦
          </p>
        )}
      </Card>
    );
  };

  renderFooterActions = () => {
    const { loading, onClose } = this.props;
    const { selectedItems } = this.state;

    return (
      <div style={{ margin: 24 }}>
        <Button
          key="back"
          type="ghost"
          size="large"
          onClick={e => {
            e.preventDefault();
            onClose();
          }}>
          取消
        </Button>
        <Button
          key="submit"
          type="primary"
          size="large"
          loading={loading}
          disabled={selectedItems.length === 0}
          onClick={this.handleSubmit}>
          保存
        </Button>
      </div>
    );
  };

  render() {
    let { knowledgeTotal } = this.props;

    const paginParams = {
      current: this.filters.page,
      pageSize: this.filters.pageSize,
      total: knowledgeTotal,
      onChange: this.onPageChange,
    };

    return (
      <CustomModal
        width={800}
        footer={
          <React.Fragment>
            {this.renderFooterSelected()}
            {this.renderFooterActions()}
          </React.Fragment>
        }>
        <Card bordered={false}>{this.renderSearchPanel()}</Card>
        <Card id="tag_content_box" style={{ marginTop: 24, minHeight: 120 }}>
          {this.renderKnowledges()}
          <div className="clear-both" />
          <LoadableCustomPagination {...paginParams} />
        </Card>
      </CustomModal>
    );
  }
}

interface OwnProps {
  handleSubmitCallback: (ids: number[]) => any;
  onClose: () => any;
  loading: boolean;
}

function mapStateToProps(state: any, ownProps: OwnProps) {
  const { loading, onClose, handleSubmitCallback } = ownProps;
  const { knowledgeList, knowledgeTotal } = state.knowledge;

  return {
    loading,
    knowledgeList,
    knowledgeTotal,
    onClose,
    handleSubmitCallback,
  };
}

export default connect(mapStateToProps)(Form.create()(PopToSelect));
